package tools;

/*
 * Author: Gianna Gibo
 * Edited By: Samantha CHoy
 * Date: July 26, 2014
 * File name: EventInput.java
 * Function: User interface to take user input for an event including event name, 
 *                      event start date-time, event end date-time, and event location and 
 *                      converts the information to an ICS file
 * Input: user input
 * Output: ICS file
 * 
 * 
 * More info about this project can be found at https://code.google.com/p/ics314-sum14-amur-cal/
 */

import java.io.*;

public class EventCreator {
	
/* Main variable declaration */	
	private String summary;
	private String classType; 
	private int timeZone; 
	private String eventPriority;
	private String eventLocation; 
    private String[] eventStartDate;
    private String[] eventStartTime;
    private String[] eventEndDate;
    private String[] eventEndTime;
    private String[] eventLength; 
    private String eventFreq;
    private String[] eventRecurEndDate;
    private String eventExdate;
 
/* Constant declaration */	
    private final String ICS = "ics";
    
/* Constructors */    
    public EventCreator() {
    	summary = "none";
    	classType = "none"; 
    	timeZone =  -1; 
    	eventPriority = "none";
    	eventLocation = "none"; 
    	eventFreq = "none";
        eventExdate = "";
    }

 /* Set Methods
  * 
  * Function: set event information
  * Input: the indicated parameters for each function
  * Output: boolean (true if information was set successfully; false otherwise)
  */
    
    public boolean setSummary (String newSummary) {
    	summary = newSummary.trim();
    	return true;
    }
    
    public boolean setClassType (String newClassType) {
    	newClassType = newClassType.trim();
    	if(newClassType.equals("PUBLIC") || newClassType.equals("PRIVATE") || newClassType.equals("CONFIDENTIAL")) {
    		classType = "" + newClassType;
            return true;
        } 
    	else {
    		return false;
        }
    }
   
    public boolean setTimeZone(int newTimeZone) {
    	if (Validator.isValidChoice(0, AmurTools.timezonesLong.length-1, newTimeZone) == true) {
    		timeZone = newTimeZone;
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    /*
     * Input: int
     * Output: true, if int is an acceptable priority value; false, otherwise
     */
    public boolean setPriority(int newPriority) {
    	if (Validator.isValidPriority(newPriority)) {
    		eventPriority = "" + newPriority;
    		return true;
    	}
    	else {
    		return false;
    	}	
    }
    
    public boolean setLocation(String newLocation) {
    	eventLocation = newLocation.trim();
    	return true;
    }
    
    public boolean setStartDate(int newYear, int newMonth, int newDay) {
    	String[] tempStartDate = {"yyyy","MM","dd"};
    	tempStartDate[0] = AmurTools.makeZeroFilled(newYear, 4);
    	tempStartDate[1] = AmurTools.makeZeroFilled(newMonth, 2);
    	tempStartDate[2] = AmurTools.makeZeroFilled(newDay, 2);
    	if (Validator.isValidDate(tempStartDate[1] + "/" + tempStartDate[2] + "/" + tempStartDate[0])) {
    		eventStartDate = tempStartDate;
    		return true;
    	}
    	else {
    		return false;
    	}    	
    }
    
    public boolean setStartTime(int newHour, int newMin, int newSec) {
    	String[] tempStartTime = {"HH", "mm", "ss"};
    	tempStartTime[0] = AmurTools.makeZeroFilled(newHour, 2);
    	tempStartTime[1] = AmurTools.makeZeroFilled(newMin, 2);
    	tempStartTime[2] = AmurTools.makeZeroFilled(newSec, 2);
    	if (Validator.isValidTime(tempStartTime[0] + ":" + tempStartTime[1] + ":" + tempStartTime[2])) {
    		eventStartTime = tempStartTime;
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    public boolean setEndDate(int newYear, int newMonth, int newDay) {
    	String[] tempEndDate = {"yyyy","MM","dd"};
    	tempEndDate[0] = AmurTools.makeZeroFilled(newYear, 4);
    	tempEndDate[1] = AmurTools.makeZeroFilled(newMonth, 2);
    	tempEndDate[2] = AmurTools.makeZeroFilled(newDay, 2);
    	if (Validator.isValidDate(tempEndDate[1] + "/" + tempEndDate[2] + "/" + tempEndDate[0])) {
    		eventEndDate = tempEndDate;
    		return true;
    	}
    	else {
    		return false;
    	}    	
    }
    
    public boolean setEndTime(int newHour, int newMin, int newSec) {
    	String[] tempEndTime = {"HH", "mm", "ss"};
    	tempEndTime[0] = AmurTools.makeZeroFilled(newHour, 2);
    	tempEndTime[1] = AmurTools.makeZeroFilled(newMin, 2);
    	tempEndTime[2] = AmurTools.makeZeroFilled(newSec, 2);
    	if (Validator.isValidTime(tempEndTime[0] + ":" + tempEndTime[1] + ":" + tempEndTime[2])) {
    		eventEndTime = tempEndTime;
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    public boolean setLength(int newHour, int newMin) {
    	String[] tempLength = {"HH", "mm"};
    	tempLength[0] = "" + newHour;
    	tempLength[1] = "" + newMin;
    	if (Validator.isValidChoice(0, 59, newMin) == true) {
    		eventLength = tempLength;
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    public boolean setFreq(String newFreq) {
    	if (newFreq.equals("DAILY") || newFreq.equals("WEEKLY") || newFreq.equals("MONTHLY") || newFreq.equals("YEARLY")) {
    		eventFreq = newFreq;
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    public boolean setRecurEndDate(int newYear, int newMonth, int newDay) {
    	String[] tempEndDate = {"yyyy","MM","dd"};
    	tempEndDate[0] = AmurTools.makeZeroFilled(newYear, 4);
    	tempEndDate[1] = AmurTools.makeZeroFilled(newMonth, 2);
    	tempEndDate[2] = AmurTools.makeZeroFilled(newDay, 2);
    	if (Validator.isValidDate(tempEndDate[1] + "/" + tempEndDate[2] + "/" + tempEndDate[0])) {
    		eventRecurEndDate = tempEndDate;
    		return true;
    	}
    	else {
    		return false;
    	}    	
    	
    }
    
    public boolean setExdate(int newYear, int newMonth, int newDay) {
    	String tempDate = "" + newMonth + "/" + newDay + "/" + newYear + " " + this.getStartTime("");
    	if ((Validator.isValidEvent(this.getStartDateTime(""), tempDate) == true) 
    			&& (Validator.isValidEvent(tempDate, this.getRecurEndDate("")) == true)) {
    		eventExdate = eventExdate + AmurTools.makeZeroFilled(newYear, 4) + AmurTools.makeZeroFilled(newMonth, 2) + AmurTools.makeZeroFilled(newDay, 2) 
    				+ "T" + this.getStartTime(ICS) + ",";
    		return true;
    	}
    	else {
    		return false;
    	}
    }
    
    public boolean resetExdate() {
    	eventExdate = "";
    	return true;
    }
    
    
 /* Get Methods 
  * 
  * Function: returns event information as strings
  * Input: String
  * Output: String (in ICS format if "ICS"; in human-readable format, otherwise) 
  */
    public String getSummary(String option) {
    	if (option.equalsIgnoreCase(ICS)) {
    		return summary;
    	}
    	else {
    		if (summary.isEmpty()) {
    			return "(No title)";
    		}
    		else {
    			return summary;
    		}	
    	}
    }
    
    public String getClassType (String option) {
    	return classType;
    }

    public String getTimeZone(String option) {
    	if (option.equalsIgnoreCase(ICS) || option.equalsIgnoreCase("long")) {
    		return AmurTools.timezonesLong[timeZone];
    	}
    	else if (option.equalsIgnoreCase("short")) {
    		return AmurTools.timezones[timeZone];
    	}
    	else {
    		return AmurTools.timezones[timeZone];
    	}
    }
    // are there descriptions for each priority?
    public String getPriority(String option) {
    	if (option.equalsIgnoreCase(ICS)) {
    		return eventPriority;
    	}
    	else {
    		return eventPriority;
    	}	
    }
    
    public String getLocation(String option) {
    	if (option.equalsIgnoreCase(ICS)) {
    		return eventLocation;
    	}
    	else {
    		if (eventLocation.isEmpty()) {
    			return "(no location)";
    		}
    		else {
    			return eventLocation;
    		}
    	}
    }
    
    public String getStartDate(String option) {
    	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		for (int i = 0; i < eventStartDate.length; i++) {
    			temp = temp + eventStartDate[i];
    		}
    	}
    	else {
    		temp = eventStartDate[1] + "/" + eventStartDate[2] + "/" + eventStartDate[0];
    	}  	
    	return temp;
    }
    
    public String getStartTime(String option) {
    	String temp ="";
    	int i = 0;
    	if (option.equalsIgnoreCase(ICS)) {
    		for (i = 0; i < eventStartTime.length; i++) {
    			temp = temp + eventStartTime[i];
    		}
    	}
    	else {
    		for (i = 0; i < eventStartTime.length; i++) {
    			temp = temp + eventStartTime[i];
    			if (i < eventStartTime.length - 1) {
    				temp = temp + ":";
    			}
    		}
    	}
    	return temp;
    }
    
    public String getStartDateTime(String option) {
    	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		temp = this.getStartDate(option) + "T" + this.getStartTime(option);
    	}
    	else {
    		temp = this.getStartDate(option) + " " + this.getStartTime(option);
    	}
    	return temp;
    }
    
    public String getEndDate(String option) {
    	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		for (int i = 0; i < eventEndDate.length; i++) {
    			temp = temp + eventEndDate[i];
    		}
    	}
    	else {
    		temp = eventEndDate[1] + "/" + eventEndDate[2] + "/" + eventEndDate[0];
    	}
    	return temp;	
    }
    
    public String getEndTime(String option) {
    	String temp ="";
    	int i = 0;
    	if (option.equalsIgnoreCase(ICS)) {
    		for (i = 0; i < eventEndTime.length; i++) {
    			temp = temp + eventEndTime[i];
    		}
    	}
    	else {
    		for (i = 0; i < eventEndTime.length; i++) {
    			temp = temp + eventEndTime[i];
    			if (i < eventEndTime.length - 1) {
    				temp = temp + ":";
    			}
    		}
    	}
    	return temp;
    }
    
    public String getEndDateTime(String option) {
       	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		temp = this.getEndDate(option) + "T" + this.getEndTime(option);
    	}
    	else {
    		temp = this.getEndDate("") + " " + this.getEndTime("");
    	}
    	return temp;
    }
    
    public String getLength(String option) {
    	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		temp = "PT" + eventLength[0] + "H" + eventLength[1] + "M";
    	}
    	else {
    		temp = eventLength[0] + "H" + eventLength[1] + "M";
    	}
    	return temp;
    }
    
    public String getFreq(String option) {
    	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		temp = "" + "FREQ=" + eventFreq + ";";
    	}
    	else {
    		temp = eventFreq;
    	}
    	return temp;
    }
    
    public String getRecurEndDate(String option) {
       	String temp = "";
    	if (option.equalsIgnoreCase(ICS)) {
    		temp = temp + "UNTIL=";
    		for (int i = 0; i < eventRecurEndDate.length; i++) {
    			temp = temp + eventRecurEndDate[i];
    		}
    		temp = temp + "T235959";
    	}
    	else {
    		temp = eventRecurEndDate[1] + "/" + eventRecurEndDate[2] + "/" + eventRecurEndDate[0] + " 23:59:59";
    	}
    	return temp;
    }
    
    public String getRRule(String option) {
    	String temp = "";
    	temp = this.getFreq(ICS) + this.getRecurEndDate(ICS);
    	return temp;
    }
    
    public String getExdate() {
    	return eventExdate;
    }
    
    
/* ICS File generator Methods 
 * 
 * Function: Converts event information into an exportable .ics file
 * Input: Strings
 * Output: .ics file
 */
        
 /* creates regular ICS file (single event; no recurring events) */
    public static void createICSFile(String newSummary, String newClassType, String newTimeZone, String newPriority, String newLocation, 
            String newStart, String newEnd) throws FileNotFoundException {
     String textOutput = "BEGIN:VCALENDAR\nPRODID://Google Inc//Google Calendar 70.9053//EN\nVERSION:2.0\nCALSCALE:GREGORIAN"
   + "\nBEGIN:VTIMEZONE\nTZID:" + newTimeZone + "\nEND:VTIMEZONE\nBEGIN:VEVENT\nDTSTART:" + newStart + "\nDTEND:" + newEnd
         + "\nCLASS:" + newClassType + "\nPRIORITY:" + newPriority + "\nLOCATION:" + newLocation + "\nSUMMARY:" + newSummary
         + "\nEND:VEVENT\nEND:VCALENDAR";
     PrintWriter myFile = new PrintWriter("amurCalendar.ics");
     myFile.println(textOutput);
     myFile.close();
    }
   
   /* creates ICS file with recurring events (and exceptions, if necessary) */
    public static void createICSFileRecur(String newSummary, String newClassType, String newTimeZone, String newPriority, String newLocation, 
                                     String newStart, String newLength, String newRRule, String newExdate) throws FileNotFoundException {
     String textOutput = "BEGIN:VCALENDAR\nPRODID://Google Inc//Google Calendar 70.9053//EN\nVERSION:2.0\nCALSCALE:GREGORIAN"
   + "\nBEGIN:VTIMEZONE\nTZID:" + newTimeZone + "\nEND:VTIMEZONE\nBEGIN:VEVENT\nDTSTART:" + newStart + "\nDURATION:" + newLength
       + "\nRRULE:" + newRRule;
     if (!newExdate.equals("")) {
       textOutput = textOutput + "\nEXDATE:" + newExdate;
     }
       textOutput = textOutput + "\nCLASS:" + newClassType + "\nPRIORITY:" + newPriority + "\nLOCATION:" + newPriority + "\nSUMMARY:" + newSummary
         + "\nEND:VEVENT\nEND:VCALENDAR";
     PrintWriter myFile = new PrintWriter("amurCalendar.ics");
     myFile.println(textOutput);
     myFile.close();
    }

}


/*

Version (section 3.7.4 of RFC 5545) 
• Classification (3.8.1.3). Note this is a way of users designating events as 
public (default), private, or confidential.
• Geographic Position (3.8.1.6)
• Priority (3.8.1.9)
• Summary (3.8.1.12) 
• DTSTART (3.8.2.4) 
• DTEND (3.8.2.2) 
• Time zone identifier (3.8.3.1) 
• And some aspect  (your choice) of recurring events


eventSummary, classType, timeZone, eventPriority, eventLocation, eventStart, eventLength, eventRRule, eventExdate


BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:Pacific/Honolulu
END:VTIMEZONE
BEGIN:VEVENT
DTSTART:20140810T100000
DURATION:PT1H
RRULE:FREQ=DAILY;UNTIL=20140831T235959
EXDATE:20140820T100000
CLASS:PRIVATE
PRIORITY:1
LOCATION:Library
SUMMARY:Study
END:VEVENT
END:VCALENDAR


*/